import pandas as pd
import numpy as np
from faker import Faker
from datetime import datetime, timedelta
import os

# 初始化Faker，设置中文
fake = Faker('zh_CN')

# 设置随机种子以保证结果可重现
np.random.seed(42)
Faker.seed(42)

# 创建输出目录
output_dir = r"D:\大三上\大数据分析及数据可视化\《Excel数据可视化 - 从图表到数据大屏》-清华-郭宏远\实验"
os.makedirs(output_dir, exist_ok=True)


def generate_erp_order_data(n=1000):
    """生成聚水潭订单数据表数据"""
    data = []

    # 预定义一些固定的选项，确保数据一致性
    status_options = ['已付款', '已发货', '已完成', '已取消']
    sub_status_options = ['待发货', '已发货', '已完成', '已取消']
    refund_status_options = ['未申请退款', '退款中', '成功退款', '退款关闭']
    platforms = ['淘宝', '天猫', '京东', '拼多多', '抖音']
    provinces = ['北京市', '上海市', '广东省', '江苏省', '浙江省', '四川省', '湖北省', '陕西省']

    # 城市映射
    cities_map = {
        '北京市': ['北京市'],
        '上海市': ['上海市'],
        '广东省': ['广州市', '深圳市', '东莞市'],
        '江苏省': ['南京市', '苏州市', '无锡市'],
        '浙江省': ['杭州市', '宁波市', '温州市'],
        '四川省': ['成都市', '绵阳市', '乐山市'],
        '湖北省': ['武汉市', '宜昌市', '襄阳市'],
        '陕西省': ['西安市', '宝鸡市', '咸阳市']
    }

    # 店铺名称
    stores = ['时尚服饰旗舰店', '潮流前线专卖店', '精品女装商城', '男装优选店铺',
              '童装天地', '运动户外专营', '内衣家居馆', '配饰精品店']

    # 服装类商品名称
    clothing_products = [
        '纯棉圆领T恤', '修身牛仔裤', '连帽卫衣', '休闲衬衫', '运动长裤',
        '针织开衫', '羽绒服', '风衣外套', '连衣裙', '半身裙',
        'Polo衫', '休闲短裤', '毛衣', '夹克外套', '西装裤'
    ]

    # 颜色规格组合
    color_specs = [
        '黑色/S', '白色/M', '灰色/L', '蓝色/XL', '红色/S',
        '绿色/M', '黄色/L', '紫色/XL', '粉色/S', '棕色/M'
    ]

    # 生成一些固定的用户ID，允许重复
    user_ids = [f"USER{fake.random_number(digits=8)}" for _ in range(200)]  # 200个用户ID用于1000条数据

    # 生成一些固定的SPU和SKU
    spu_list = [f"SPU{fake.random_number(digits=6)}" for _ in range(100)]
    sku_list = [f"SKU{fake.random_number(digits=8)}" for _ in range(300)]

    # 设置时间范围
    end_date = datetime.now()
    start_date = end_date - timedelta(days=365)  # 一年前

    for i in range(n):
        # 生成订单时间（最近一年内）- 使用更兼容的方法
        days_ago = np.random.randint(0, 365)
        order_time = start_date + timedelta(days=days_ago,
                                            hours=np.random.randint(0, 24),
                                            minutes=np.random.randint(0, 60))

        # 确保付款日期在订单时间之后（1分钟到24小时内）
        payment_date = order_time + timedelta(
            hours=np.random.randint(0, 24),
            minutes=np.random.randint(1, 60)
        )

        # 确保发货日期在付款日期之后（1-7天内）
        shipping_date = payment_date + timedelta(days=np.random.randint(1, 7))

        # 选择省份和对应的城市
        province = np.random.choice(provinces)
        city = np.random.choice(cities_map[province])

        # 商品数量
        quantity = np.random.randint(1, 5)

        # 商品单价
        unit_price = round(np.random.uniform(50, 300), 2)

        # 计算商品金额
        product_amount = round(quantity * unit_price, 2)

        # 原价（比单价高10%-50%）
        original_price = round(unit_price * np.random.uniform(1.1, 1.5), 2)

        # 应付金额（商品金额+运费）
        payable_amount = round(product_amount + np.random.uniform(8, 20), 2)

        # 已付金额（等于应付金额）
        paid_amount = payable_amount

        # 退款相关数量
        refund_status = np.random.choice(refund_status_options, p=[0.85, 0.05, 0.05, 0.05])
        if refund_status == '成功退款':
            actual_refund_quantity = np.random.randint(1, quantity + 1)
            registered_quantity = actual_refund_quantity
        else:
            actual_refund_quantity = 0
            registered_quantity = quantity

        record = {
            'id': i + 1,
            'internal_order_number': f"IN{fake.random_number(digits=8)}",
            'online_order_number': f"ON{fake.random_number(digits=10)}",
            'store_name': np.random.choice(stores),
            'full_channel_user_id': np.random.choice(user_ids),  # 允许重复的用户ID
            'shipping_date': shipping_date,
            'payment_date': payment_date,
            'payable_amount': payable_amount,
            'paid_amount': paid_amount,
            'status': np.random.choice(status_options, p=[0.4, 0.3, 0.2, 0.1]),
            'consignee': fake.name(),
            'spu': np.random.choice(spu_list),
            'order_time': order_time,
            'province': province,
            'city': city,
            'platform': np.random.choice(platforms),
            'sub_order_number': f"SUB{fake.random_number(digits=8)}",
            'online_sub_order_number': f"OSUB{fake.random_number(digits=8)}",
            'original_online_order_number': f"ORG{fake.random_number(digits=8)}",
            'sku': np.random.choice(sku_list),
            'quantity': quantity,
            'unit_price': unit_price,
            'product_name': np.random.choice(clothing_products),  # 统一为服装类商品
            'color_and_spec': np.random.choice(color_specs),
            'product_amount': product_amount,
            'original_price': original_price,
            'is_gift': '否',  # 大部分订单不是赠品
            'sub_order_status': np.random.choice(sub_status_options, p=[0.3, 0.4, 0.2, 0.1]),
            'refund_status': refund_status,
            'registered_quantity': registered_quantity,
            'actual_refund_quantity': actual_refund_quantity
        }
        data.append(record)

    return pd.DataFrame(data)


def main():
    print("开始生成ERP订单数据...")

    # 生成ERP订单数据
    erp_df = generate_erp_order_data(1000)

    # 检查是否有空值
    print("检查数据完整性...")
    null_check = erp_df.isnull().sum()
    if null_check.sum() == 0:
        print("✓ 所有字段都没有空值")
    else:
        print("发现空值字段:")
        print(null_check[null_check > 0])

    # 保存为Excel文件
    excel_file_path = os.path.join(output_dir, 'erp_order_data.xlsx')

    # 确保日期格式正确
    date_columns = ['shipping_date', 'payment_date', 'order_time']
    for col in date_columns:
        erp_df[col] = erp_df[col].dt.strftime('%Y-%m-%d %H:%M:%S')

    erp_df.to_excel(excel_file_path, index=False, engine='openpyxl')

    print(f"\n数据生成完成！")
    print(f"数据保存路径: {excel_file_path}")
    print(f"总记录数: {len(erp_df)} 条")

    # 显示一些统计信息
    print("\n数据统计信息:")
    print(f"用户ID重复情况: {erp_df['full_channel_user_id'].nunique()} 个唯一用户")
    print(f"商品种类: {erp_df['product_name'].nunique()} 种服装商品")
    print(f"平台分布: {erp_df['platform'].value_counts().to_dict()}")
    print(f"状态分布: {erp_df['status'].value_counts().to_dict()}")

    # 生成数据预览
    print("\n数据预览:")
    print(erp_df.head(3).to_string())

    # 生成requirements.txt
    requirements = """pandas>=1.3.0
numpy>=1.20.0
faker>=8.0.0
openpyxl>=3.0.0
"""

    with open(os.path.join(output_dir, 'requirements.txt'), 'w', encoding='utf-8') as f:
        f.write(requirements)

    print(f"\n依赖文件已生成: requirements.txt")


if __name__ == "__main__":
    main()